package com.jinwei.qunguanjia.system.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.jinwei.qunguanjia.system.dao.SysDeptDAO;
import com.jinwei.qunguanjia.system.dto.SysDeptDTO;
import com.jinwei.qunguanjia.system.dto.SysRoleDTO;
import com.jinwei.qunguanjia.system.dto.SysUserDTO;
import com.jinwei.qunguanjia.system.po.SysDeptPO;
import com.jinwei.qunguanjia.common.constant.UserConstants;
import com.jinwei.qunguanjia.common.core.domain.model.Condition;
import com.jinwei.qunguanjia.common.exception.GlobalExceptionHelper;
import com.jinwei.qunguanjia.common.utils.*;
import com.jinwei.qunguanjia.system.utils.SecurityUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.List;

/**
 * 部门管理 服务层实现
 *
 * @author ruoyi
 */
@Service("sysDeptService")
public class SysDeptServiceImpl implements SysDeptService {

    @Resource
    private SysDeptDAO sysDeptDAO;

    @Resource
    private SysUserService sysUserService;

    @Resource
    private SysRoleService sysRoleService;

    @Override
    public void save(SysDeptDTO sysDeptDTO) throws IllegalAccessException {
        SysDeptDTO info = get(SysDeptDTO.builder().parentId(sysDeptDTO.getParentId()).build());
        // 如果父节点不为正常状态,则不允许新增子节点
        if (!UserConstants.DEPT_NORMAL.equals(info.getDeptStatus())) {
            throw GlobalExceptionHelper.localServiceException("部门停用，不允许新增");
        }
        sysDeptDTO.setAncestors(info.getAncestors() + "," + sysDeptDTO.getParentId());
        SysDeptPO sysDeptPO = new SysDeptPO();
        BeanUtils.copyProperties(sysDeptDTO, sysDeptPO);
        sysDeptPO.setDeptId(IdUtils.getWorkerId());
        sysDeptDAO.insert(sysDeptPO);
    }

    @Override
    public void remove(String id) {
        sysDeptDAO.deleteById(id);
    }

    @Override
    public void update(SysDeptDTO sysDeptDTO) throws IllegalAccessException {
        SysDeptDTO newParentDept = get(SysDeptDTO.builder().parentId(sysDeptDTO.getParentId()).build());
        SysDeptDTO oldDept = get(SysDeptDTO.builder().parentId(sysDeptDTO.getDeptId()).build());
        if (StringUtils.isNotNull(newParentDept) && StringUtils.isNotNull(oldDept))
        {
            String newAncestors = newParentDept.getAncestors() + "," + newParentDept.getDeptId();
            String oldAncestors = oldDept.getAncestors();
            sysDeptDTO.setAncestors(newAncestors);
            updateDeptChildren(sysDeptDTO.getDeptId(), newAncestors, oldAncestors);
        }
        SysDeptPO sysDeptPO = new SysDeptPO();
        BeanUtils.copyProperties(sysDeptDTO, sysDeptPO);
        sysDeptDAO.updateById(sysDeptPO);
        if (UserConstants.DEPT_NORMAL.equals(sysDeptDTO.getDeptStatus()) && StringUtils.isNotEmpty(sysDeptDTO.getAncestors())
                && !StringUtils.equals("0", sysDeptDTO.getAncestors()))
        {
            LambdaUpdateWrapper<SysDeptPO> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
            String ancestors = sysDeptDTO.getAncestors();
            List<String> deptIds = Arrays.asList(ancestors.split(","));
            lambdaUpdateWrapper.set(SysDeptPO::getDeptStatus, "0");
            lambdaUpdateWrapper.in(SysDeptPO::getDeptId, deptIds);
            // 如果该部门是启用状态，则启用该部门的所有上级部门
            sysDeptDAO.update(null, lambdaUpdateWrapper);
        }
    }

    /**
     * 修改子元素关系
     *
     * @param deptId 被修改的部门ID
     * @param newAncestors 新的父ID集合
     * @param oldAncestors 旧的父ID集合
     */
    private void updateDeptChildren(String deptId, String newAncestors, String oldAncestors)
    {
        List<SysDeptDTO> children = sysDeptDAO.selectChildrenDeptById(deptId);
        for (SysDeptDTO child : children)
        {
            child.setAncestors(child.getAncestors().replaceFirst(oldAncestors, newAncestors));
        }
        if (children.size() > 0)
        {
            sysDeptDAO.updateDeptChildren(children);
        }
    }

    @Override
    public SysDeptDTO get(String id) {
        SysDeptPO sysDeptPO = sysDeptDAO.selectById(id);
        if (null == sysDeptPO) {
            return null;
        }
        SysDeptDTO sysDeptDTO = new SysDeptDTO();
        BeanUtils.copyProperties(sysDeptPO, sysDeptDTO);
        return sysDeptDTO;
    }

    @Override
    public SysDeptDTO get(SysDeptDTO sysDeptDTO) throws IllegalAccessException {
        // 添加查询条件
        List<Condition> conditionList = ConditionUtils.add(sysDeptDTO);
        // 拼接查询条件
        QueryWrapper<SysDeptPO> queryWrapper = SearchUtils.parseWhereSql(conditionList);
        SysDeptPO sysDeptPO = sysDeptDAO.selectOne(queryWrapper);
        if (null == sysDeptPO) {
            return null;
        }
        BeanUtils.copyProperties(sysDeptPO, sysDeptDTO);
        return sysDeptDTO;
    }

    @Override
    public Long count(SysDeptDTO sysDeptDTO) throws IllegalAccessException {
        // 添加查询条件
        List<Condition> conditionList = ConditionUtils.add(sysDeptDTO);
        // 拼接查询条件
        QueryWrapper<SysDeptPO> queryWrapper = SearchUtils.parseWhereSql(conditionList);
        return sysDeptDAO.selectCount(queryWrapper);
    }

    @Override
    public Integer countNormalChildrenDeptById(String deptId) {
        return sysDeptDAO.countNormalChildrenDeptById(deptId);
    }

    @Override
    public List<SysDeptDTO> list(SysDeptDTO sysDeptDTO) {
        return sysDeptDAO.listDept(sysDeptDTO);
    }

    @Override
    public List<String> listDeptByRoleId(String roleId) {
        SysRoleDTO sysRoleDTO = sysRoleService.get(roleId);
        return sysDeptDAO.listDeptByRoleId(roleId, sysRoleDTO.isDeptCheckStrictly());
    }

    @Override
    public void checkDeptDataScope(String deptId) {
        if (!SecurityUtils.isAdmin()) {
            SysDeptDTO dept = new SysDeptDTO();
            dept.setDeptId(deptId);
            List<SysDeptDTO> deptList = list(dept);
            if (StringUtils.isEmpty(deptList)) {
                throw GlobalExceptionHelper.localServiceException("没有权限访问部门数据");
            }
        }
    }

    @Override
    public String checkDeptNameUnique(SysDeptDTO sysDeptDTO) throws IllegalAccessException {
        String deptId = StringUtils.isNull(sysDeptDTO.getDeptId()) ? "-1" : sysDeptDTO.getDeptId();
        SysDeptDTO info = get(SysDeptDTO.builder().deptName(sysDeptDTO.getDeptName()).parentId(sysDeptDTO.getParentId()).build());
        if (StringUtils.isNotNull(info) && !info.getDeptId().equals(deptId)) {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }

    @Override
    public boolean hasChildByDeptId(String deptId) throws IllegalAccessException {
        long result = count(SysDeptDTO.builder().parentId(deptId).build());
        return result > 0;
    }

    @Override
    public boolean checkDeptExistUser(String deptId) throws IllegalAccessException {
        long result = sysUserService.count(SysUserDTO.builder().deptId(deptId).build());
        return result > 0;
    }
}
